﻿using System;
using System.Windows.Forms;
using LinkDownloader.Core;
using System.Collections.Generic;
using LinkDownloader.DownloadManger;
using LinkDownloader.Forms.JobLists;
using System.ComponentModel;

namespace LinkDownloader.Forms
{
    internal partial class frmMain : Form
    {
        
        private const int BalloonTimeout = 2000; // 2 secs (2000 milisecs)

        public enum ViewState
        {
            All,
            Active,
            Cancelled,
            Completed,
            New,
            Paused
        }

        private MainDownloader downloader = null;

        private ViewState view = ViewState.All;

        private DataGridViewCell activeCell = null;

        private FormWindowState previousState = FormWindowState.Normal;

        private bool forceClose = false;
        
        public frmMain(MainDownloader downloader)
        {

            this.InitializeComponent();

            this.downloader = (downloader != null) ? downloader : new MainDownloader();
            
        }

        public void DoSplashInitialization(frmSplash splash)
        {

            this.NiceInitializing(splash, 800,"Initializing...");
            this.jobList.CompleteInitialization();
            
            this.NiceInitializing(splash, 800, "Loading settings...");
            GlobalSettings.LoadSettings();
            this.downloader.SaveDirectory = GlobalSettings.Settings.SaveDirectory;
            this.downloader.JobCompleted += new Downloader.ChangedEventHandler(downloader_JobCompleted);
            
            this.NiceInitializing(splash, 800, "Loading categories...");
            this.treeView.ExpandAll();
            
            this.NiceInitializing(splash, 800, "Loading history...");
            this.txtSearch.ShowEmpty();
            
            splash.EndLoading();

        }

        private void NiceInitializing(frmSplash splash, int time50, string status)
        {
            splash.UpdateProgress(splash.Progress, status);
            for (int i = 0; i < time50; i+=50)
            {
                System.Threading.Thread.Sleep(50);
                splash.UpdateProgress(splash.Progress + 2);
            }            
        }

        private void downloader_JobCompleted(int id, ChangedEventArgs e)
        {
            // testing
            if (e.Success) { MessageBox.Show("success"); }
        }
        
        private void Add_Click(object sender, EventArgs e)
        {
            frmAddNew fAdd = new frmAddNew();
            fAdd.FileDirectory = this.downloader.SaveDirectory;
            if (fAdd.ShowDialog(this) == DialogResult.OK)
            {
                this.downloader.SaveDirectory = fAdd.FileDirectory;
                GlobalSettings.Settings.SaveDirectory = fAdd.FileDirectory; // REVISE
                this.AddNewLinks(fAdd.Links, fAdd.FileDirectory);
            }
        }

        private void AddNewLinks(string[] links, string fileDirectory)
        {
            DownloadJob[] added = this.downloader.AddNewDownloads(links);
            foreach (SingleDownload d in added)
            {
                d.FileDirectory = fileDirectory;
                d.InitializeRow(this.jobList); 
            }
            this.ShowJobs();
        }

        private void ShowJobs()
        {

            switch (this.view)
            {

                case ViewState.All:

                    List<DownloadJob> list = new List<DownloadJob>(this.downloader.AllJobCount);
                    foreach (DownloadJob d in this.downloader.ActiveJobs) { list.Add(d); }
                    foreach (DownloadJob d in this.downloader.OnlineJobs) { list.Add(d); }
                    foreach (DownloadJob d in this.downloader.CompletedJobs) { list.Add(d); }
                    foreach (DownloadJob d in this.downloader.CancelledJobs) { list.Add(d); }
                    this.RefreshList(list);
                    break;

            }

        }

        private void RefreshList(List<DownloadJob> list)
        {

            this.jobList.SuspendLayout();
            this.jobList.Rows.Clear();

            foreach (SingleDownload d in list)
            {
                this.jobList.Rows.Add(d.Row);
            }

            this.jobList.ResumeLayout();

        }

        private void jobList_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex >= 0 && e.RowIndex < this.jobList.RowCount)
            {
                this.activeCell = this.jobList[e.ColumnIndex, e.RowIndex];
            }
        }

        private void jobList_Leave(object sender, EventArgs e)
        {
            this.activeCell = null;
        }

        private void jobList_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            this.activeCell = null;
        }

        private void mnuSingleJob_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.activeCell == null) { e.Cancel = true; }
        }

        private void jobList_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex >= 0 && e.RowIndex < this.jobList.RowCount)
            {
                this.activeCell = this.jobList[e.ColumnIndex, e.RowIndex];
            }
        }

        private void StartSelected_Click(object sender, EventArgs e)
        {
            foreach (JobListRow row in this.jobList.SelectedRows)
            {
                row.DownloadJob.StartDownload();
            }
        }

        private void PauseSelected_Click(object sender, EventArgs e)
        {
            foreach (JobListRow row in this.jobList.SelectedRows)
            {
                row.DownloadJob.PauseDownload();
            }
        }

        private void StopSelected_Click(object sender, EventArgs e)
        {
            foreach (JobListRow row in this.jobList.SelectedRows)
            {
                row.DownloadJob.CancelDownload();
            }
        }

        private void tbnHelp_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Help not implemented yet!");
        }

        private void mnuFileExit_Click(object sender, EventArgs e)
        {
            this.ForceExitApplication();
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!this.forceClose && GlobalSettings.Settings.MinimizeToSystemTray)
            {
                this.MinimiseToSystemTray();
                e.Cancel = true;
            }
        }

        private void ExitProgram()
        {

            // use this block to close the application without asking confirmation
            this.Close();

            // use this block to ask for confirmation
            //string msg = "Are you sure you want to exit Link Downloader?";
            //if (MessageBox.Show(msg, "Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            //{
            //    this.Close();
            //}

        }

        private void MinimiseToSystemTray()
        {
            this.WindowState = FormWindowState.Minimized;
            this.Hide();
            this.notifyIcon.Visible = true;
            if (GlobalSettings.Settings.ShowMessageWhenMinimized)
            {
                string msg = "Link Downloader has minimized to the system tray.";
                this.notifyIcon.ShowBalloonTip(BalloonTimeout, "Link Downloader working in the background", msg, ToolTipIcon.None);
            }
        }

        private void OpenFromSystemTray()
        {
            this.Show();
            this.WindowState = this.previousState;            
            this.notifyIcon.Visible = false;
        }

        private void mnuHelpAbout_Click(object sender, EventArgs e)
        {
            frmAbout fAbout = new frmAbout();
            fAbout.ShowDialog(this);
        }
                
        private void frmMain_ResizeBegin(object sender, EventArgs e)
        {
            if (this.WindowState != FormWindowState.Minimized) { this.previousState = this.WindowState; }
        }

        private void mnuHelpViewHelp_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Help not implemented yet!");
        }

        private void Notify_DoubleClick(object sender, EventArgs e)
        {
            this.OpenFromSystemTray();
        }

        private void mnuNotifyOpen_Click(object sender, EventArgs e)
        {
            this.OpenFromSystemTray();
        }

        private void ShowOptions()
        {
            frmOptions fOptions = new frmOptions();
            if (fOptions.ShowDialog(this) == DialogResult.OK)
            {
                // add what ever needs to be done.
                // keep in mind that the SaveSettings (private) method in the options form usaully handles the settings
            }
        }

        private void mnuNotifyOptions_Click(object sender, EventArgs e)
        {
            this.ShowOptions();
        }

        private void mnuToolsOptions_Click(object sender, EventArgs e)
        {
            this.ShowOptions();
        }

        private void mnuSingleProperties_Click(object sender, EventArgs e)
        {
            if (this.activeCell != null)
            {
                JobListRow row = this.activeCell.OwningRow as JobListRow;
                row.DownloadJob.Show();
            }
        }

        private void mnuSingleStart_Click(object sender, EventArgs e)
        {
            if (this.activeCell != null)
            {
                JobListRow row = this.activeCell.OwningRow as JobListRow;
                row.DownloadJob.StartDownload();
            }
        }

        private void mnuSinglePause_Click(object sender, EventArgs e)
        {
            if (this.activeCell != null)
            {
                JobListRow row = this.activeCell.OwningRow as JobListRow;
                row.DownloadJob.PauseDownload();
            }
        }

        private void mnuSingleStop_Click(object sender, EventArgs e)
        {
            if (this.activeCell != null)
            {
                JobListRow row = this.activeCell.OwningRow as JobListRow;
                row.DownloadJob.CancelDownload();
            }
        }

        private void mnuSingleDelLink_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Delete Link not implemented yet!");
        }

        private void mnuSingleDelLinkData_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Delete Link and Data not implemented yet!");
        }

        private void tbnSearch_Click(object sender, EventArgs e)
        {
            if (!this.txtSearch.IsShowingEmptyText) { this.DoSearch(this.txtSearch.Text); }
        }

        private void txtSearch_EnterKeyPressed(object sender, KeyEventArgs e)
        {
            if (!this.txtSearch.IsShowingEmptyText) { this.DoSearch(this.txtSearch.Text); }
        }

        private void DoSearch(string str)
        {
            MessageBox.Show("Search not implemented yet!");
        }

        private void mnuNotifyExit_Click(object sender, EventArgs e)
        {
            this.ForceExitApplication();
        }

        public void ForceExitApplication()
        {
            this.forceClose = true;
            this.ExitProgram();
            this.forceClose = false; // incase the user decides to cancel the action via message box;
        }

        private void minimizeToSystemTrayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.ExitProgram();
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            GlobalSettings.SaveSettings();
            this.downloader.Splash.ForceClose();
        }
                
    }
}
